package controllers

import (
	"git.oschina.net/fanbuchi/timemaker/models"
	"git.oschina.net/fanbuchi/timemaker/valid"
	"github.com/astaxie/beego"
	"github.com/astaxie/beego/orm"
	"github.com/satori/go.uuid"

	"time"
)

//oauth2 authorize
type Oauth2Controller struct {
	beego.Controller
}

func (this *Oauth2Controller) authorization() {

}

// @Author killerzhangsan
// @Title authorizator
// @Description 生成app基础信息
// @Param   client_id     header    string  true        "The client_id"
// @Param   basic        header  string  true        "basic token"
// @Param   package_name     query    string  true        "The package_name"
// @Success 200 ok
// @router /authorizator [post]
func (this *Oauth2Controller) Authorizator() {
	packageName := this.GetString("package_name")
	clientDetails, err := models.MakeClientDetails(packageName)
	if err != nil {
		this.Data[dataformat] = models.ObjectStatus{models.BusinessError, err.Error()}
		this.ServeJson()
		return
	}
	this.Data[dataformat] = clientDetails
	this.ServeJson()
}

// @Author killerzhangsan
// @Title authorize
// @Description app Authorize
// @Param   client_id     header    string  true        "The client_id"
// @Param   basic        header  string  true        "basic token"
// @Param   user_name     form    string  true        "user_name"
// @Param   password     form    string  true        "password"
// @Success 200 ok
// @router /authorize [post]
func (this *Oauth2Controller) Authorize() {
	client := models.Client{}
	if err := this.ParseForm(&client); err != nil {
		this.Data[dataformat] = models.ObjectStatus{models.BusinessError, err.Error()}
		this.ServeJson()
		return
	}
	os := valid.ValidClient(&client)
	if os.Status != models.Ok {
		this.Data[dataformat] = os
		this.ServeJson()
		return
	}

	o := orm.NewOrm()
	//查询账号密码
	profile := models.Profile{UserName: client.UserName, Password: client.Password}
	err := o.Read(&profile, "UserName", "Password")
	if err != nil {
		this.Data[dataformat] = models.ObjectStatus{models.BusinessError, "user_name or password error"}
		this.ServeJson()
		return
	}

	//更新授权时间和授权token
	clientToken := models.ClientToken{UserId: profile.UserId,
		AccessToken:  uuid.NewV4().String(),
		RefreshToken: uuid.NewV4().String(),
		TokenTime:    time.Now()}
	num, err := o.Update(&clientToken, "AccessToken", "RefreshToken", "TokenTime")
	if err != nil {
		this.Data[dataformat] = models.ObjectStatus{models.BusinessError, err.Error()}
		this.ServeJson()
		return
	}
	if num < 1 {
		this.Data[dataformat] = models.ObjectStatus{models.BusinessError, "authorize error"}
		this.ServeJson()
		return
	}
	//查询授权信息
	err = o.Read(&clientToken)
	if err != nil {
		this.Data[dataformat] = models.ObjectStatus{models.BusinessError, "authorize error"}
		this.ServeJson()
		return
	}

	this.Data[dataformat] = clientToken
	this.ServeJson()
}

// @Author killerzhangsan
// @Title refreshToken
// @Description 刷新授权
// @Param   client_id     header    string  true        "The client_id"
// @Param   basic     header    string  true        "The refresh_Token"
// @Param   bear     header    string  true        "The refresh_Token type"
// @Success 200 ok
// @router /refreshToken [get]
func (this *Oauth2Controller) RefreshToken() {
	refreshToken := this.Ctx.Input.Header("basic") ///refresh_Token
	refresh_Token := this.Ctx.Input.Header("bearer")
	if refresh_Token != "refresh_Token" {
		this.Data[dataformat] = models.ObjectStatus{models.BusinessError, "bear must be refresh_Token"}
		this.ServeJson()
		return
	}
	o := orm.NewOrm()
	//查询授权信息
	clientToken := models.ClientToken{RefreshToken: refreshToken}
	err := o.Read(&clientToken, "RefreshToken")
	if err != nil {
		this.Data[dataformat] = models.ObjectStatus{models.BusinessError, "authorize error"}
		this.ServeJson()
		return
	}

	//更新授权时间和授权token
	clientToken.AccessToken = uuid.NewV4().String()
	clientToken.RefreshToken = uuid.NewV4().String()
	clientToken.TokenTime = time.Now()

	num, err := o.Update(&clientToken)
	if err != nil || num < 1 {
		this.Data[dataformat] = models.ObjectStatus{models.ServerError, "authorize error"}
		this.ServeJson()
		return
	}
	this.Data[dataformat] = clientToken
	this.ServeJson()
}
